mbs-script-search is a focused search UI for FileMaker/MBS script XML exports. It loads a Base64-encoded XML source, builds a client-side search index, and lets you search script names, script IDs, group paths, script steps, and step arguments from one interface.
The project is built with Vite and packaged as a single-file web app for easy embedding and deployment.
The search can match in these areas:
Each result groups all matches per script, so one script can show multiple matching areas at once.
Type into the search field to search immediately. Input is debounced slightly, so the app waits a short moment before running the search.
The search is normalized before matching:
CamelCase, underscores, paths, and mixed letters/numbersThis means many common formatting differences are ignored automatically.
You can override the default case-insensitive behavior with the Case-sensitive search checkbox in the actions menu.
Exact vs TolerantThese buttons control how strictly terms are matched.
They apply only when the query mode is set to Text and case-sensitive search is not active.
ExactExact means no fuzzy typo matching is applied.
It still benefits from the app’s normalization and token segmentation, so it is not “case-sensitive exact” in the strict literal sense. In practice, Exact means:
Use Exact when you know the term, function name, script name, or ID closely enough and want tighter results.
TolerantTolerant is the broader MiniSearch-driven mode.
In practice, Tolerant uses MiniSearch more directly, especially for script names, IDs, paths, and individual step areas. This means tolerant mode is much better suited for:
Examples:
SetVarible may still find Set Variableset varible excel can now work as a tolerant multi-word queryUse Tolerant when you want MiniSearch to do the broader work for you.
Text vs RegexThese buttons control how the content of the search field is interpreted.
TextText is the default mode.
In this mode, the app uses the existing normalized text search pipeline together with the selected Exact or Tolerant logic and the selected All or Any term mode.
If Case-sensitive search is enabled, Text mode switches to a case-sensitive exact matching path and Tolerant becomes inactive.
RegexRegex treats the search field as a JavaScript regular expression.
In this mode:
Logic and Terms are visible but inactive because they do not apply to regex matching/pattern/giCase-sensitive search is enabled, regex matching is forced to be case-sensitiveUse Regex when you need advanced pattern matching that is more precise than text search.
Examples:
Set\s+Variable
Set Variable with flexible spacing\b(?:Import|Export)\b
Import or Export^If\b
If\b[A-Z]{2,}_\d+\b
FOO_123(?=.*excel)(?=.*import)
excel[\s\S]*import|import[\s\S]*excel
excel followed by import or vice versaPractical notes:
set\s+variable uses the app default regex flags/set\s+variable/i uses the flags you provide explicitly/set\s+variable/ without i is case-sensitiveCase-sensitive search is enabled, the i flag is ignored so regex matching stays case-sensitiveHighlighting note:
excel.*import or excel[\s\S]*import|import[\s\S]*excelAll vs AnyThese buttons control how multiple search terms are combined.
They apply only when the query mode is set to Text.
They still apply when case-sensitive text search is active.
AllAll query terms must match.
In practice, the current implementation requires all terms to be found within the same searchable area, for example:
This behavior is preserved in both Exact and Tolerant mode.
Use All to narrow the result list when you know multiple parts of the target text.
AnyAny one of the entered terms may match.
This is broader and helpful when:
This behavior is also preserved in both Exact and Tolerant mode.
After searching, you can reduce visible matches using the filter chips:
The chips also show counts, so you can see how many matches belong to each category.
Results support several interaction modes:
Show moreThe summary line below the toolbar reports loading state, match counts, and empty states.
The vertical three-dot button opens a native browser popover. It currently contains:
The action buttons are configured to close the popover after a short delay, so transient button feedback remains visible. The checkboxes do not close the popover.
Copy results copies the currently visible result set to the clipboard.
If Summarized results only is not checked, each step is copied with full text:
- Set Variable - Line 41: full step content here
If Summarized results only is checked, step matches are copied in a condensed two-line format:
- Set Variable - Line 41
- Contents: shortened preview here
This is useful when you want compact output without losing the step identity.
The app starts in src/main.js, mounts the UI, then loads and indexes the XML data.
High-level flow:
src/main.js mounts mountScriptSearchApp()The current data source is imported from:
src/searchData.js (or src/searchData_mbs.js for MBS-specific data)The exported variable is:
SCRIPTS_XML_BASE64The XML is:
DOMParserThe index is built with MiniSearch.
Indexed fields:
scriptIdnamepathstepContentStored fields:
idscriptIdnamepathEach script contributes:
The current implementation combines several matching layers:
Query mode selection
Text uses the standard search pipelineRegex uses direct JavaScript regular expression matchingCase sensitivity
Case-sensitive search switches text search to a direct case-sensitive matching pathRegex mode, regex matching is forced to be case-sensitiveNormalization
Segmentation
_, ., /, \\, >, -Prefix support
Fuzzy support
Tolerant modePost-filter validation
Exact mode still uses stricter app-side validation and contains-style fallback matchingTolerant mode relies more directly on MiniSearch result behavior through a dedicated area-based indexRegex mode bypasses the text query logic and evaluates patterns directly against searchable areasThe current score boost configuration favors these fields:
This keeps likely script hits near the top while still surfacing deep step matches.
Main UI responsibilities:
src/main.js
src/scriptSearchApp.js
src/style.css
These constants currently influence behavior directly in src/scriptSearchApp.js:
| Constant | Current value | Effect |
|---|---|---|
PAGE_SIZE |
100 |
Number of result groups initially rendered before Show more is used. |
SEARCH_INPUT_DEBOUNCE_MS |
120 |
Delay before the search runs after typing. |
INDEX_BATCH_SIZE |
20 |
Number of scripts indexed per async batch. |
MIN_PREFIX_TERM_LENGTH |
2 |
Minimum length before prefix matching is used. |
MIN_FUZZY_TERM_LENGTH |
4 |
Minimum term length before tolerant fuzzy matching may activate. |
STEP_PREVIEW_MAX_LINES |
6 |
Step preview/UI threshold used in result rendering logic. |
STEP_TOGGLE_MIN_LENGTH |
220 |
Length threshold used for step expansion behavior. |
COPY_SUMMARY_PREVIEW_LENGTH |
200 |
Maximum number of characters included in summarized copy mode previews. |
CONTROLS_POPOVER_OFFSET |
8 |
Vertical spacing between the popover trigger and the popover. |
CONTROLS_POPOVER_CLOSE_DELAY_MS |
220 |
Delay before close-enabled popover actions close the menu. |
LINKING_ENABLED |
true |
Enables deep-link/navigation behavior in result links. |
Related configuration objects:
FILTER_OPTIONSSEARCH_MODE_OPTIONSSEARCH_LOGIC_OPTIONSDEFAULT_SEARCH_BOOSTID_SEARCH_BOOSTThe build uses Vite with:
vite-plugin-singlefilevite-plugin-minifyCurrent behavior from vite.config.js:
__APP_VERSION__ from package.jsonAvailable npm scripts from package.json:
npm run dev
npm run build
npm run build-mbs
npm run build-release
npm run upload
npm run deploy-to-fm
>=22This project is a single-file, browser-based search tool for FileMaker/MBS script XML. It supports:
If you want to change how the search feels, the first place to check is src/scriptSearchApp.js, especially the search option arrays, the matching helpers, the score boosts, and the constants listed above.